﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UFramework.Tools
{
    /// <summary>数组助手类</summary>
    internal static class ArrayHelper
    {
        /// <summary>
        ///根据指标求最大的元素
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <typeparam name="Tkey">指标的类型</typeparam>
        /// <param name="students">数组</param>
        /// <param name="conditon">取指标的委托</param>
        /// <returns></returns>
        public static T Max<T, Tkey>(T[] students, Func<T, Tkey> conditon) where Tkey : IComparable
        {
            T max = students[0];
            for (int i = 1; i < students.Length; i++)
            {
                if (conditon(students[i]).CompareTo(conditon(max)) > 0)//把取指标推迟给调用者
                {
                    max = students[i];
                }
            }
            return max;
        }
        /// <summary>
        ///根据指标求最小的元素
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <typeparam name="Tkey">指标的类型</typeparam>
        /// <param name="students">数组</param>
        /// <param name="conditon">取指标的委托</param>
        /// <returns></returns>
        public static T Min<T, Tkey>(T[] students, Func<T, Tkey> conditon) where Tkey : IComparable
        {
            T min = students[0];
            for (int i = 1; i < students.Length; i++)
            {
                if (conditon(students[i]).CompareTo(conditon(min)) < 0)//把取指标推迟给调用者
                {
                    min = students[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 选择符合条件的对象
        /// </summary>
        /// <typeparam name="T">数组的类型</typeparam>
        /// <param name="array">数组</param>
        /// <param name="conditon">条件委托</param>
        /// <returns></returns>
        public static List<T> Find<T>(T[] array, Func<T, bool> conditon)
        {
            List<T> result = new List<T>();
            for (int i = 0; i < array.Length; i++)
            {
                if (conditon(array[i]))//发条件判断推迟给调用者
                {
                    result.Add(array[i]);
                }
            }
            return result;
        }

        /// <summary>
        /// 根据某一个指标排序(升序)
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <typeparam name="Tkey">指标类型</typeparam>
        /// <param name="array">数组</param>
        /// <param name="conditon">取指标的委托</param>
        public static void SortAsc<T, Tkey>(T[] array, Func<T, Tkey> conditon) where Tkey : IComparable
        {
            int minIndex;
            T temp;

            for (int j = 0; j < array.Length - 1; j++)//取开始位置
            {
                //每次从未未排序的中选一个最小的放在前面
                minIndex = j;//最小值的索引,假设第0 个是最小的
                for (int i = j + 1; i < array.Length; i++)
                {
                    if (conditon(array[i]).CompareTo(conditon(array[minIndex])) < 0)// 把取指标推迟给调用者
                    {
                        minIndex = i;
                    }
                }
                temp = array[j];
                array[j] = array[minIndex];
                array[minIndex] = temp;
            }
        }

        /// <summary>
        /// 根据某一个指标排序(降序)
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <typeparam name="Tkey">指标类型</typeparam>
        /// <param name="array">数组</param>
        /// <param name="conditon">取指标的委托</param>
        public static void SortDesc<T, Tkey>(T[] array, Func<T, Tkey> conditon) where Tkey : IComparable
        {
            int maxIndex;
            T temp;

            for (int j = 0; j < array.Length - 1; j++)//取开始位置
            {
                //每次从未未排序的中选一个最小的放在前面
                maxIndex = j;//最小值的索引,假设第0 个是最小的
                for (int i = j + 1; i < array.Length; i++)
                {
                    if (conditon(array[i]).CompareTo(conditon(array[maxIndex])) > 0)//把取指标推迟给调用者
                    {
                        maxIndex = i;
                    }
                }
                temp = array[j];
                array[j] = array[maxIndex];
                array[maxIndex] = temp;
            }
        }
        /// <summary>
        /// 多条件排序
        /// </summary>
        /// <typeparam name="T">数组类型</typeparam>
        /// <param name="array">数组</param>
        /// <param name="conditon">条件判断的委托</param>

        public static void SortMultConditon<T>(T[] array, Func<T, T, bool> conditon)
        {
            int index;
            T temp;

            for (int j = 0; j < array.Length - 1; j++)//取开始位置
            {
                //每次从未未排序的中选一个最小的放在前面
                index = j;//最小值的索引,假设第0 个是最小的
                for (int i = j + 1; i < array.Length; i++)
                {
                    if (conditon(array[i], array[index]))//把比比较的条件 推迟给调用者定义
                    {
                        index = i;
                    }
                }
                temp = array[j];
                array[j] = array[index];
                array[index] = temp;
            }
        }
    }
}